package com.excel.poi.sax;

import com.excel.poi.sax.inter.AnalysisContextImpl;
import com.excel.poi.sax.inter.ExcelAnalyser;
import com.excel.annotation.PoiExcel;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zw
 * @Description 基础解析
 * @create /2022/3/25
 */
public abstract class BaseSaxAnalyser implements AnalysisEventRegisterCenter, ExcelAnalyser {
    protected AnalysisContextImpl analysisContext;

    private LinkedHashMap<String, AnalysisEventListener> listeners = new LinkedHashMap<String, AnalysisEventListener>();

    /**
     * execute method
     */
    public abstract void execute() throws Exception;


    @Override
    public void appendLister(String name, AnalysisEventListener listener) {
        if (!listeners.containsKey(name)) {
            listeners.put(name, listener);
        }
    }

    @Override
    public void analysis() throws Exception {
        execute();
    }
    /**
     * 清除监听器
     */
    public void cleanAllListeners() {
        listeners = new LinkedHashMap<String, AnalysisEventListener>();
    }

    /**
     * 解析一行以通知所有事件侦听器
     * @param event 解析事件
     */
    public void notifyListeners(OneRowAnalysisFinishEvent event) throws Exception {
        analysisContext.setCurrentRowAnalysisResult(event.getData());
        /**
          解析头信息
          **/
        if (analysisContext.getCurrentRowNum() < analysisContext.getCurrentSheet().getHeadLineMun()) {
            if (analysisContext.getCurrentRowNum() <= analysisContext.getCurrentSheet().getHeadLineMun() - 1) {

                analysisContext.buildExcelHeadProperty(null,
                    (List<String>)analysisContext.getCurrentRowAnalysisResult());
            }
        } else {
            /** 解析分析正文内容 **/
          /*  analysisContext.setCurrentRowAnalysisResult(event.getData());
            if (listeners.size() == 1) {
                analysisContext.setCurrentRowAnalysisResult(mappingField((List<String>)event.getData()));
            }*/
            analysisContext.setCurrentRowAnalysisResult(mappingField((List<String>)event.getData()));
            /**    通知所有事件监听器**/
            for (Map.Entry<String, AnalysisEventListener> entry : listeners.entrySet()) {
                entry.getValue().invoke(analysisContext.getCurrentRowAnalysisResult(), analysisContext);
            }
        }
    }
    public List<SheetParam> getSheets() throws Exception {
        return null;
    }
    //要做的实现映射为class对象
    //补充 必须字段一定要抛异常
    private Object mappingField(List<String> data) throws Exception {
        ExcelHeadProperty excelHeadProperty = analysisContext.getExcelHeadProperty();
        Class<?> clazz = excelHeadProperty.getHeadClazz();
        Object object = clazz.newInstance();
        Map<Integer, Field> linkFieldMap = excelHeadProperty.getLinkFieldMap();
        if (data != null) {
            for (int i = 0; i < data.size(); i++) {
                // TypeUtil.formatFloat(data.get(i))
                Object stringCellValue = data.get(i);
                if(linkFieldMap.containsKey(i)){
                    Field field = linkFieldMap.get(i);
                    saveFieldValue(field,object,stringCellValue);
                }
            }
        }

        return object;
    }
    private Object replaceValue(String[] replace, String value) {
        String[] temp;
        for (String str : replace) {
            temp = str.split("_");
            if (value.equals(temp[1])) {
                value = temp[0];
                break;
            }
        }
        return value;
    }
    /**
     * 反射给属性赋值(可以增加匹配类型，)
     *
     * @param field
     * @param object
     */
    private void saveFieldValue(Field field, Object object, Object stringCellValue) throws Exception {
        //校验一下 是否是必填字段啊
        field.setAccessible(true);
        PoiExcel p = field.getAnnotation(PoiExcel.class);
        if (p.importIsMust()) {
            if (StringUtils.isEmpty((String)stringCellValue)) {
                throw new Exception(p.name() + "不能为空");
            }
        }
        if (null == stringCellValue) {
            return;
        }
        String[] importReplace = p.importReplace();
        if (importReplace != null && importReplace.length > 0) {
            stringCellValue = replaceValue(importReplace, (String)stringCellValue);
        }
        //导入后缀解析
        String importSuffix = p.importSuffix();
        if (StringUtils.isNotEmpty(importSuffix)) {
            stringCellValue = stringCellValue + importSuffix;
        }
        String importFormat = p.importFormat();
        if (StringUtils.isNotEmpty(importFormat)) {
            SimpleDateFormat format = new SimpleDateFormat(importFormat);
            try {
                stringCellValue = format.parse((String)stringCellValue);
            } catch (ParseException e) {
                throw e;
            }
        }
        String type = field.getType().toString();
        if (type.endsWith("String") && null != stringCellValue) {
            field.set(object, stringCellValue); // 给属性设值
        } else if (type.endsWith("int") || type.endsWith("Integer") && null != stringCellValue) {
            field.set(object, Integer.valueOf((String)stringCellValue));
                  /*  try {
                        field.set(object, Integer.valueOf((String)stringCellValue));
                    } catch (Exception e) {
                        //格式错误的时候,就用double,然后获取Int值
                        field.set(object, Double.valueOf((String)stringCellValue).intValue());
                    }*/
        } else if (type.endsWith("char") && null != stringCellValue) {
            field.set(object, ((String)stringCellValue).charAt(0));
        } else if (type.endsWith("BigDecimal") && null != stringCellValue) {
            field.set(object, new BigDecimal((String)stringCellValue));
        } else if (type.endsWith("List") && null != stringCellValue) {
            // 给属性设值
            field.set(object, new ArrayList<>().add(stringCellValue));
        } else if (type.endsWith("Long") && null != stringCellValue) {
          //  field.set(object, Long.valueOf((String)stringCellValue));
                    try {
                        field.set(object,Long.valueOf((String)stringCellValue));
                    } catch (Exception e) {
                        //格式错误的时候,就用double,然后获取Int值
                        field.set(object,Double.valueOf((String)stringCellValue).longValue());
                    }
        } else if ((type.endsWith("Float") || type.endsWith("float")) && null != stringCellValue) {
            field.set(object, Float.valueOf((String)stringCellValue));
        } else if ((type.endsWith("Boolean") || type.endsWith("boolean")) && null != stringCellValue) {
            field.set(object, Boolean.valueOf((String)stringCellValue));
        } else if ((type.endsWith("Double") || type.endsWith("double")) && null != stringCellValue) {
            field.set(object, Double.valueOf((String)stringCellValue));
        } else if ((type.endsWith("Date") || type.endsWith("Date")) && null != stringCellValue) {
            //具体包下类型自己实现
            field.set(object, stringCellValue);
        } else {
            field.set(object, stringCellValue);
        }

    }
}
